﻿using Microsoft.SharePoint.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebJobAsTimerService.Models;

namespace WebJobAsTimerService
{
    public class SharePointListProcessor
    {
        //private string listName;
        private ClientContext clientContext;
        private List spList;
        private IConfiguration configuration;
        private EmailService emailService;

        public SharePointListProcessor(IConfiguration configuration)
        {
            this.configuration = configuration;

            // Open connection to Office365 tenant
            clientContext = new ClientContext(configuration.SharePointSiteUrl);
            clientContext.AuthenticationMode = ClientAuthenticationMode.Default;
            clientContext.Credentials = new SharePointOnlineCredentials(configuration.SharePointUserName, configuration.SharePointUserPassword);
            
            // getting list
            this.spList = clientContext.Web.Lists.GetByTitle(configuration.SharePointListName);
            clientContext.Load(spList);
            clientContext.ExecuteQuery();

            if(spList == null)
                throw new ArgumentNullException(string.Format("Could not find list: '{0}'", configuration.SharePointListName));

            //creating office365 email service
            emailService = new EmailService(configuration);
        }

        public void Process()
        {   
            //Get all items that needs to be processed
            var items = GetItemsByCamlQuery();

            foreach(var item in items)
            {
                try
                {
                    Console.WriteLine("Processing Id: {0}, Email: {1}, Status: {2}", item.Id, item["Email"], item["Status"]);
                    
                    //Step 1
                    UpdateStatus(item, "In Progress", "Updating status to 'In Progress' before sending email.");

                    //Step 2
                    SendEmail(item);

                    //Step 3
                    UpdateStatus(item, "Processed", "Updating status to 'Processed' after sending email.");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: {0}", ex.Message);
                    UpdateStatus(item, "Error Occurred", "Exception: " + ex.Message);
                }
            }
        }

        private void UpdateStatus(ListItem item, string newStatus, string comments)
        {
            Console.WriteLine("Updating status to '{0}' for item id: {1}", newStatus, item.Id);

            ListItem itemToBeUpdated = spList.GetItemById(item.Id);
            clientContext.Load(itemToBeUpdated);
            clientContext.ExecuteQuery();

            itemToBeUpdated["Status"] = newStatus;
            if (!string.IsNullOrWhiteSpace(comments))
            {
                itemToBeUpdated["Comments"] = itemToBeUpdated["Comments"] + comments + "\r\n";
            }

            itemToBeUpdated.Update();
            clientContext.ExecuteQuery();            
        }

        private void SendEmail(ListItem item)
        {
            Console.WriteLine("Sending email to {0}", item["Email"]);

            //Creating model using SharePoint List Item
            var emailData = new EmailTemplateModel()
            {
                FirstName = item["FirstName"].ToString(),
                LastName = item["LastName"].ToString()
            };

            var toAddress = item["Email"].ToString();
            var subject = "This is test email from SharePoint timer service";

            //Creating email body using template and above data
            var emailBody = TemplateManager.GetEmailBody("EmailTemplate.html", emailData);

            //Sending email using Office365 account
            emailService.SendEmail(toAddress, subject, emailBody, true);
        }

        private ListItemCollection GetItemsByCamlQuery()
        {
            CamlQuery camlQuery = new CamlQuery();
            camlQuery.ViewXml = configuration.EmailListFilterCamlQueryString;

            ListItemCollection listItems = spList.GetItems(camlQuery);
            clientContext.Load(listItems);
            clientContext.ExecuteQuery();

            return listItems;
        }
    }
}
